#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.basic.security.oauth2.custom;

import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * Description:
 *  自定义授权页面
 *
 * @author wupanhua
 * @date 2020-04-25 17:24
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
@Controller
@SessionAttributes("authorizationRequest")
public class YkWhitelabelApprovalEndpoint {

    @RequestMapping("/oauth/custom/confirm_access")
    public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception {
        final String approvalContent = createTemplate(model, request);
        if (request.getAttribute("_csrf") != null) {
            model.put("_csrf", request.getAttribute("_csrf"));
        }
        View approvalView = new View() {
            @Override
            public String getContentType() {
                return "text/html";
            }

            @Override
            public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
                response.setContentType(getContentType());
                response.getWriter().append(approvalContent);
            }
        };
        return new ModelAndView(approvalView, model);
    }

    protected String createTemplate(Map<String, Object> model, HttpServletRequest request) {
        AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");
        String clientId = authorizationRequest.getClientId();

        StringBuilder builder = new StringBuilder();
        builder.append("<html><meta content=${symbol_escape}"text/html;charset=utf-8${symbol_escape}"><script src=${symbol_escape}"http://how2j.cn/study/js/jquery/2.0.0/jquery.min.js${symbol_escape}"></script><style>${symbol_escape}n" +
                "<style>*{padding:0px;margin:0px;}h1{text-align:center}.wrap{width:480px;height:550px;background-color:${symbol_pound}fff;padding:40px;position:fixed;left:50%;top:50%;transform:translateX(-50%) translateY(-50%);box-shadow:0.3rem 0.3rem 3rem ${symbol_pound}999d9c;box-sizing:border-box;}.login-title{text-align:center;padding-bottom:34px;font-size:18px;font-family:SourceHanSansCN-Regular;font-weight:600;color:rgba(22,94,159,1);border-bottom:1px solid rgba(224,224,224,1);display:flex;align-items:center;justify-content:center;}.login-tips{margin:40px 9px;font-size:17px;}.login-img{width:100%;height:100px;text-align:center;box-sizing:border-box;}.login-img img:first-child{width:80px;margin-right:30px;}.login-img img:nth-child(2){width:50px;}.login-img img:last-child{width:60px;margin-left:30px;}ul{list-style-type:none;margin-top:40px;}li{margin-top:20px;margin-left:8px;}.btn-primary{margin-top: 35px;width:100%;height:38px;cursor:pointer;background-color:${symbol_pound}4399d3;color:${symbol_pound}fff;border:0;font-size:16px;font-weight:600;letter-spacing:8px;text-align:center;}li:last-child input{background:${symbol_pound}fff;color:${symbol_pound}ccc;margin: 0 8px 0 10px;}ul:last-child{padding-right:8px;}</style>" +
                "<body><div class=wrap><div class=login-title><span class=slogan>云科凯创单点登陆授权页面</span></div>");

        builder.append("<p class=${symbol_escape}"login-tips${symbol_escape}">您是否授权 ${symbol_escape}"").append(HtmlUtils.htmlEscape(clientId));
        builder.append("${symbol_escape}" 访问您的受保护资源？</p>");
        builder.append("<div class=${symbol_escape}"login-img${symbol_escape}"><img src=${symbol_escape}"http://oss.cloudscope.cn/public/header_logo.png${symbol_escape}" alt=${symbol_escape}"${symbol_escape}"><img src=${symbol_escape}"http://oss.cloudscope.cn/public/cahnge.png${symbol_escape}" alt=${symbol_escape}"${symbol_escape}" class=${symbol_escape}"icon${symbol_escape}"> <img src=${symbol_escape}"http://oss.cloudscope.cn/public/gitlab.png${symbol_escape}" alt=${symbol_escape}"${symbol_escape}" class=${symbol_escape}"icon${symbol_escape}"></div>");
        builder.append("<form id=${symbol_escape}"confirmationForm${symbol_escape}" name=${symbol_escape}"confirmationForm${symbol_escape}" action=${symbol_escape}"");

        String requestPath = ServletUriComponentsBuilder.fromContextPath(request).build().getPath();
        if (requestPath == null) {
            requestPath = "";
        }

        builder.append(requestPath).append("/api/v1/auth/oauth/authorize${symbol_escape}" method=${symbol_escape}"post${symbol_escape}">");
        builder.append("<input name=${symbol_escape}"user_oauth_approval${symbol_escape}" value=${symbol_escape}"true${symbol_escape}" type=${symbol_escape}"hidden${symbol_escape}"/>");

        String csrfTemplate = null;
        CsrfToken csrfToken = (CsrfToken) (model.containsKey("_csrf") ? model.get("_csrf") : request.getAttribute("_csrf"));
        if (csrfToken != null) {
            csrfTemplate = "<input type=${symbol_escape}"hidden${symbol_escape}" name=${symbol_escape}"" + HtmlUtils.htmlEscape(csrfToken.getParameterName()) +
                    "${symbol_escape}" value=${symbol_escape}"" + HtmlUtils.htmlEscape(csrfToken.getToken()) + "${symbol_escape}" />";
        }
        if (csrfTemplate != null) {
            builder.append(csrfTemplate);
        }

        String authorizeInputTemplate = "<label><input name=${symbol_escape}"authorize${symbol_escape}" value=${symbol_escape}"Authorize${symbol_escape}" type=${symbol_escape}"submit${symbol_escape}" class=${symbol_escape}"btn btn-primary${symbol_escape}"/></label></form>";

        if (model.containsKey("scopes") || request.getAttribute("scopes") != null) {
            builder.append(createScopes(model, request));
            builder.append(authorizeInputTemplate);
        } else {
            builder.append(authorizeInputTemplate);
            builder.append("<form id=${symbol_escape}"denialForm${symbol_escape}" name=${symbol_escape}"denialForm${symbol_escape}" action=${symbol_escape}"");
            builder.append(requestPath).append("/api/v1/auth/oauth/authorize${symbol_escape}" method=${symbol_escape}"post${symbol_escape}">");
            builder.append("<input name=${symbol_escape}"user_oauth_approval${symbol_escape}" value=${symbol_escape}"false${symbol_escape}" type=${symbol_escape}"hidden${symbol_escape}"/>");
            if (csrfTemplate != null) {
                builder.append(csrfTemplate);
            }
            builder.append("<label><input name=${symbol_escape}"deny${symbol_escape}" value=${symbol_escape}"Deny${symbol_escape}" type=${symbol_escape}"submit${symbol_escape}"/></label></form>");
        }

        builder.append("</body></html>");

        return builder.toString();
    }

    private CharSequence createScopes(Map<String, Object> model, HttpServletRequest request) {
        StringBuilder builder = new StringBuilder("<ul>");
        @SuppressWarnings("unchecked")
        Map<String, String> scopes = (Map<String, String>) (model.containsKey("scopes") ?
                model.get("scopes") : request.getAttribute("scopes"));
        for (String scope : scopes.keySet()) {
            String approved = "true".equals(scopes.get(scope)) ? " checked" : "";
            String denied = !"true".equals(scopes.get(scope)) ? " checked" : "";
            scope = HtmlUtils.htmlEscape(scope);

            builder.append("<li><div class=${symbol_escape}"form-group${symbol_escape}">");
            builder.append(scope).append(": <input type=${symbol_escape}"radio${symbol_escape}" name=${symbol_escape}"");
            builder.append(scope).append("${symbol_escape}" value=${symbol_escape}"true${symbol_escape}"").append(approved).append(">Approve</input> ");
            builder.append("<input type=${symbol_escape}"radio${symbol_escape}" name=${symbol_escape}"").append(scope).append("${symbol_escape}" value=${symbol_escape}"false${symbol_escape}"");
            builder.append(denied).append(">Deny</input></div></li>");
        }
        builder.append("</ul>");
        return builder.toString();
    }
}
